package com.ihome.excel.xlsx.engine.imports;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import com.ihome.excel.xlsx.annotation.ISBigDecimal;
import com.ihome.excel.xlsx.annotation.ISEmail;
import com.ihome.excel.xlsx.annotation.ISIdCard;
import com.ihome.excel.xlsx.annotation.ISMobile;
import com.ihome.excel.xlsx.annotation.ISNotEmpty;
import com.ihome.excel.xlsx.annotation.ISSeatPhone;
import com.ihome.excel.xlsx.annotation.StrLengthEquals;
import com.ihome.excel.xlsx.annotation.StrLengthGt;
import com.ihome.excel.xlsx.annotation.StrLengthLt;
import com.ihome.excel.xlsx.config.DataMappingConfig;
import com.ihome.excel.xlsx.entity.AttributeConfig;
import com.ihome.excel.xlsx.entity.DataType;
import com.ihome.excel.xlsx.entity.EncapsulationEnum;
import com.ihome.excel.xlsx.entity.TemplateConfig;
import com.ihome.excel.xlsx.entity.ValidateRule;
import com.ihome.excel.xlsx.exceptions.ThrowableDefine;

@SuppressWarnings("all")
public class TempateParseEngine {	
	
	/**
	 * 检查导入模型配置项
	 * @param workBook
	 */
	public TemplateConfig getTemplateConfig(Workbook workBook){
		if(workBook == null){
			throw ThrowableDefine.PARAMETER_VALIDATE_EXP.getIllegaArgumentExp("workBook");
		}
		String classa = null;	
		Class classz = null;
		Field[] fields = null;
		Sheet sheet = workBook.getSheetAt(0);		
		Row classaRow = sheet.iterator().next();		
		/**
		 * 如果第一行为空则抛出异常
		 */
		if(classaRow == null){
		    throw ThrowableDefine.MAPPING_ENTITY_DEFINE_ERROR.getTemplateParseExp();			
		}		
		Cell classaCell = classaRow.getCell(0);
		classa = classaCell.getStringCellValue();
		if(classa == null || "".equals(classa)){
		    throw ThrowableDefine.MAPPING_ENTITY_DEFINE_ERROR.getTemplateParseExp();
		}
		if(!classa.equals(EncapsulationEnum.MAP.toString())){
		    /**
	         * 验证配置的映射对象是否存在
	         */
	        try {
	            classz = Class.forName(classa);
	            fields = classz.getDeclaredFields();
	        } catch (ClassNotFoundException e) {
	            throw ThrowableDefine.MAPPING_KEY_NO_DEFINE.getTemplateParseExp(classa);            
	        }
		}
		
		Row entityMappingRelationRow = sheet.iterator().next();
		/**
		 * 如果第二行 没有配置映射关系键则抛出异常
		 */
		if(entityMappingRelationRow == null){
		    throw ThrowableDefine.MAPPING_KEY_NO_DEFINE.getTemplateParseExp();
		}
		/**
		 * 取到当前模型配置的关系映射配置
		 */
		TemplateConfig config = new TemplateConfig();
		config.setClassa(classa);	
		config.setEncapEnum(EncapsulationEnum.getEncapsulationEnumByName(classa));
		int totalColumns = entityMappingRelationRow.getPhysicalNumberOfCells();
		AttributeConfig entityMa;
		String attributeName;
		Annotation[] antonations = null;
		boolean attributeExists = true;
		for(int index = 0; index < totalColumns ; index ++){
		    attributeName = entityMappingRelationRow.getCell(index).getStringCellValue();
			entityMa = new AttributeConfig(index,attributeName);
			config.getAttributeConfig().put(String.valueOf(index), entityMa);
			/**
	         * 解析实体注解配置
	         */
	        if(!classa.equals(EncapsulationEnum.MAP.toString())){
	            for(Field field : fields){
	                attributeExists = false;
	                if(field.getName().equals(attributeName)){	                    
	                    config.getDefaultValidateRule().getMap().putAll(getValidateRuleForAnnotation(index,field));
	                    attributeExists = true;
	                    break;
	                }
	            }
	            if(!attributeExists){
	                throw ThrowableDefine.MAPING_ATTRIBUTE_NO_DEFINE.getTemplateParseExp(classa,attributeName);
	            }
	        }
		}
		return config;
	}	
	
	private Map<String, ValidateRule> getValidateRuleForAnnotation(int columnIndex,Field field){
	    Map<String, ValidateRule> ruleMap = new HashMap<String, ValidateRule>();
	    ISBigDecimal isBigDecimal = field.getAnnotation(ISBigDecimal.class);
	    ISEmail isEmail = field.getAnnotation(ISEmail.class);
	    ISIdCard isIdCard = field.getAnnotation(ISIdCard.class);
	    ISMobile isMobile = field.getAnnotation(ISMobile.class);
	    ISNotEmpty isNotEmpty = field.getAnnotation(ISNotEmpty.class);
	    ISSeatPhone isSeatPhone = field.getAnnotation(ISSeatPhone.class);
	    StrLengthEquals strLengthEquals = field.getAnnotation(StrLengthEquals.class);
	    StrLengthGt strLengthGt = field.getAnnotation(StrLengthGt.class);
	    StrLengthLt strLengthLt = field.getAnnotation(StrLengthLt.class);	    
	    ValidateRule rule = new ValidateRule();
	    String fieldTypeName = field.getType().getName();
	    rule.setDataType(DataType.getDataType(DataMappingConfig.getPropertyValue(fieldTypeName)));
	    if(isBigDecimal != null){
	        rule.setBigDecimalScale(isBigDecimal.scale());
	        rule.setBigDecimalRoundMode(isBigDecimal.roundMode());
	    }
	    if(isEmail != null){
	        rule.setEmail(true);
	    }
	    if(isIdCard != null){
	        rule.setIdCard(true);
	    }
	    if(isMobile != null){
	        rule.setMobile(true);
	    }
	    if(isNotEmpty != null){
	        rule.setNotNull(true);
	    }
	    if(isSeatPhone != null){
	        rule.setSeatPhone(true);
	    }
	    if(strLengthEquals != null){
	        rule.setStrLengthEquals(strLengthEquals.length());
	    }
	    if(strLengthGt != null){
	        rule.setStrLengthGt(strLengthGt.length());
	    }
	    if(strLengthLt != null){
	        rule.setStrLengthLt(strLengthLt.length());
	    }
	    ruleMap.put(String.valueOf(columnIndex), rule);
	    return ruleMap;
	}
}
